namespace Smarts.Internal.Test.Core
{
    using System;
    using NUnit.Framework;
    using Smarts.Core;
    using TestDataDataSetTableAdapters;

    /// <summary>
    /// Tests for the Pluralize Class
    /// </summary>
    [TestFixture]
    public class PluralTests
    {
        #region Test configuration
        /// <summary>
        /// Test cleanup
        /// </summary>
        [TearDown]
        public void CleanUpAfterTests()
        {
            Plural.ClearAllExceptions();
        }
        #endregion

        #region Plural tests

        /// <summary>
        /// Tests basic pluralization
        /// </summary>
        [Test]
        [Category("Plural")]
        public void PluralizeNormal()
        {
            TestDataDataSet.PluralFormsDataTable plurals = new TestDataDataSet.PluralFormsDataTable();
            PluralFormsTableAdapter tda = new PluralFormsTableAdapter();
            tda.Fill(plurals);
            foreach (TestDataDataSet.PluralFormsRow pluralRow in plurals)
            {
                Assert.That(
                    Plural.Of(0, pluralRow.SingularForm),
                    Is.EqualTo("0 " + pluralRow.PluralForm));
                Assert.That(
                    Plural.Of(1, pluralRow.SingularForm),
                    Is.EqualTo("1 " + pluralRow.SingularForm));
                for (int i = 2; i < 1000; i++)
                {
                    Assert.That(
                        Plural.Of(i, pluralRow.SingularForm),
                        Is.EqualTo(i.ToString() + " " + pluralRow.PluralForm));
                }
            }
        }

        /// <summary>
        /// Tests pluralization with custom exceptions
        /// </summary>
        [Test]
        [Category("Pluralize")]
        public void PluralizeExceptions()
        {
            PluralExceptionsTableAdapter tda = new PluralExceptionsTableAdapter();
            TestDataDataSet.PluralExceptionsDataTable plurals = tda.GetData();
            foreach (TestDataDataSet.PluralExceptionsRow plural in plurals)
            {
                Plural.AddException(plural.SingularForm, plural.PluralForm);
                Assert.That(
                    Plural.Of(0, plural.SingularForm),
                    Is.EqualTo("0 " + plural.PluralForm));
                Assert.That(
                    Plural.Of(1, plural.SingularForm),
                    Is.EqualTo("1 " + plural.SingularForm));
                for (int i = 2; i < 1000; i++)
                {
                    Assert.That(
                        Plural.Of(i, plural.SingularForm),
                        Is.EqualTo(i.ToString() + " " + plural.PluralForm));
                }
            }
        }

        /// <summary>
        /// Tests that using negative numbers with the Pluralizer
        /// will fail when their use is disabled
        /// </summary>
        [Test]
        public void PluralizeNegativeNotAllowed()
        {
            Plural.AllowNegatives = false;
            try
            {
                Plural.Of(-1, "dog");
            }
            catch (ArgumentOutOfRangeException e)
            {
                StringAssert.StartsWith("Negative numbers have been disabled", e.Message);
                return;
            }

            Assert.Fail("Exception of type ArgumentOutOfRangeException was not thrown.");
        }

        /// <summary>
        /// Tests that negatives are pluralized properly when
        /// they are allowed
        /// </summary>
        [Test]
        public void PluralizeNegativeAllowed()
        {
            Plural.AllowNegatives = true;
            PluralFormsTableAdapter tda = new PluralFormsTableAdapter();
            TestDataDataSet.PluralFormsDataTable plurals = tda.GetData();
            foreach (TestDataDataSet.PluralFormsRow plural in plurals)
            {
                Assert.That(
                    Plural.Of(-1, plural.SingularForm),
                    Is.EqualTo("-1 " + plural.SingularForm));
                for (int i = -2; i > -1001; i--)
                {
                    Assert.That(
                        Plural.Of(i, plural.SingularForm),
                        Is.EqualTo(i.ToString() + " " + plural.PluralForm));
                }
            }
        }

        /// <summary>
        /// Tests that Pluralization of is/are is properly performed
        /// </summary>
        [Test]
        public void PluralizeIsAre()
        {
            PluralFormsTableAdapter tda = new PluralFormsTableAdapter();
            TestDataDataSet.PluralFormsDataTable plurals = tda.GetData();
            foreach (TestDataDataSet.PluralFormsRow plural in plurals)
            {
                Assert.That(
                    Plural.Is(1, plural.SingularForm),
                    Is.EqualTo("is 1 " + plural.SingularForm));
                for (int i = 2; i < 1000; i++)
                {
                    Assert.That(
                        Plural.Is(i, plural.SingularForm),
                        Is.EqualTo(string.Format("are {0} {1}", i, plural.PluralForm)));
                }
            }
        }

        /// <summary>
        /// Tests that pluralization of was/were is properly performed
        /// </summary>
        [Test]
        public void PluralizeWasWere()
        {
            PluralFormsTableAdapter tda = new PluralFormsTableAdapter();
            TestDataDataSet.PluralFormsDataTable plurals = tda.GetData();
            foreach (TestDataDataSet.PluralFormsRow plural in plurals)
            {
                Assert.That(
                    Plural.Was(1, plural.SingularForm),
                    Is.EqualTo("was 1 " + plural.SingularForm));
                for (int i = 2; i < 1000; i++)
                {
                    Assert.That(
                        Plural.Was(i, plural.SingularForm),
                        Is.EqualTo(string.Format("were {0} {1}", i, plural.PluralForm)));
                }
            }
        }

        #endregion
    }
}